package com.mini.grpc.common;

import java.util.concurrent.TimeUnit;

/**
 * 截止时间类
 * 用于表示RPC调用的超时时间
 * 
 * @author Mini-gRPC
 */
public final class Deadline implements Comparable<Deadline> {
    
    private final long deadlineNanos;
    
    /**
     * 私有构造函数
     * 
     * @param deadlineNanos 截止时间（纳秒）
     */
    private Deadline(long deadlineNanos) {
        this.deadlineNanos = deadlineNanos;
    }
    
    /**
     * 创建一个从现在开始的截止时间
     * 
     * @param duration 持续时间
     * @param unit 时间单位
     * @return 截止时间实例
     */
    public static Deadline after(long duration, TimeUnit unit) {
        if (duration <= 0) {
            throw new IllegalArgumentException("duration must be positive");
        }
        if (unit == null) {
            throw new IllegalArgumentException("unit cannot be null");
        }
        
        long durationNanos = unit.toNanos(duration);
        long currentNanos = System.nanoTime();
        
        // 检查溢出
        if (durationNanos > Long.MAX_VALUE - currentNanos) {
            return new Deadline(Long.MAX_VALUE);
        }
        
        return new Deadline(currentNanos + durationNanos);
    }
    
    /**
     * 创建一个绝对时间的截止时间
     * 
     * @param absoluteNanos 绝对时间（纳秒）
     * @return 截止时间实例
     */
    public static Deadline ofAbsoluteNanos(long absoluteNanos) {
        return new Deadline(absoluteNanos);
    }
    
    /**
     * 判断是否已过期
     * 
     * @return 如果已过期返回true
     */
    public boolean isExpired() {
        return System.nanoTime() >= deadlineNanos;
    }
    
    /**
     * 获取剩余时间（纳秒）
     * 
     * @return 剩余时间，如果已过期返回0或负数
     */
    public long timeRemainingNanos() {
        return deadlineNanos - System.nanoTime();
    }
    
    /**
     * 获取剩余时间
     * 
     * @param unit 时间单位
     * @return 剩余时间，如果已过期返回0或负数
     */
    public long timeRemaining(TimeUnit unit) {
        if (unit == null) {
            throw new IllegalArgumentException("unit cannot be null");
        }
        return unit.convert(timeRemainingNanos(), TimeUnit.NANOSECONDS);
    }
    
    /**
     * 获取截止时间的绝对值（纳秒）
     * 
     * @return 截止时间绝对值
     */
    public long getAbsoluteNanos() {
        return deadlineNanos;
    }
    
    /**
     * 创建一个更早的截止时间
     * 
     * @param other 另一个截止时间
     * @return 更早的截止时间
     */
    public Deadline minimum(Deadline other) {
        if (other == null) {
            return this;
        }
        return this.deadlineNanos <= other.deadlineNanos ? this : other;
    }
    
    /**
     * 创建一个更晚的截止时间
     * 
     * @param other 另一个截止时间
     * @return 更晚的截止时间
     */
    public Deadline maximum(Deadline other) {
        if (other == null) {
            return this;
        }
        return this.deadlineNanos >= other.deadlineNanos ? this : other;
    }
    
    @Override
    public int compareTo(Deadline other) {
        if (other == null) {
            return 1;
        }
        return Long.compare(this.deadlineNanos, other.deadlineNanos);
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        Deadline deadline = (Deadline) obj;
        return deadlineNanos == deadline.deadlineNanos;
    }
    
    @Override
    public int hashCode() {
        return Long.hashCode(deadlineNanos);
    }
    
    @Override
    public String toString() {
        long remaining = timeRemainingNanos();
        if (remaining > 0) {
            return "Deadline{remaining=" + TimeUnit.NANOSECONDS.toMillis(remaining) + "ms}";
        } else {
            return "Deadline{expired=" + TimeUnit.NANOSECONDS.toMillis(-remaining) + "ms ago}";
        }
    }
} 